import { Component, OnInit, Input } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { Observable } from 'rxjs';
import { SiteService } from '@srvs/site.service';
import { ApiService } from '@srvs/api.service';

@Component({
  selector: 'edit-user',
  templateUrl: './edit-user.component.html',
  styles: [`
    :host ::ng-deep .form-inner {
      padding: 16px 72px 0;
    }
    :host ::ng-deep .label-width {
      width: 81px;
    }
  `]
})
export class EditUserComponent implements OnInit {

  public config: any = {
    isCreate: true
  };
  public validateForm: FormGroup;

  @Input() public data: any;
  @Input() public roleOptions: any[] = [];

  constructor(
    public siteSrv: SiteService,
    private formBuilder: FormBuilder,
    private apiSrv: ApiService
  ) { }

  public ngOnInit(): void {
    let passwordValidators: [Function] = [Validators.pattern(/^$|^.{6,16}$/)],
      checkPasswordValidators: [Function] = [this.confirmPassword];

    if (this.data) {
      this.config.isCreate = false;
    } else {
      this.data = { sites: [], roles: [] };
      passwordValidators.unshift(Validators.required);
      checkPasswordValidators.unshift(Validators.required);
    }

    this.validateForm = this.formBuilder.group({
      account: [this.data.account || null, [Validators.required, Validators.minLength(5), Validators.maxLength(16)]],
      username: [this.data.username || null, [Validators.required, Validators.minLength(2), Validators.maxLength(16)]],
      email: [this.data.email || null, [Validators.required, Validators.email]],
      mobileNumber: [this.data.mobileNumber || null, [Validators.required, Validators.pattern(/^1\d{10}$/)]],
      password: ['', passwordValidators],
      checkPassword: ['', checkPasswordValidators],
      isValid: [this.data.isValid !== undefined ? this.data.isValid : null, [Validators.required]],
      expiredTime: [this.data.expiredTime || null, [Validators.required]],
      sites: [this.data.sites.map(item => item.id), [Validators.required]],
      roles: [this.data.roles.map(item => item.id), [Validators.required]]
    });
  }
  
  public updateConfirmPassword(): void {
    Promise.resolve().then(() => this.validateForm.controls.checkPassword.updateValueAndValidity());
  }

  public hasError(controlName: string): boolean {
    return !!(
      this.validateForm.get(controlName).dirty &&
      this.validateForm.get(controlName).errors
    );
  }

  public submit(): Observable<any> {
    for (const item in this.validateForm.controls) {
      this.validateForm.controls[item].markAsDirty();
      this.validateForm.controls[item].updateValueAndValidity();
    }

    if (this.validateForm.valid) {

      let params: any = Object.assign({}, this.validateForm.value);
      if (!params.password) params.password = this.data.password;
      delete params.checkPassword;
      params.roles = params.roles.map(roleId => this.roleOptions.find(role => role.id === roleId));
      params.sites = params.sites.map(siteId => this.siteSrv.getSiteById(siteId));

      const apiUser: string = '/api/users';
      if (this.config.isCreate) {
        return this.apiSrv.post(apiUser, params);
      } else {
        params.id = this.data.id;
        return this.apiSrv.put(apiUser, params);
      }

    } else {
      return new Observable(observer => observer.complete());
    }
  }

  private confirmPassword: Function = (control: FormControl): any => {
    if (
      this.validateForm &&
      control.value !== this.validateForm.controls.password.value
    ) return { confirm: true };
  }

}
